from django.shortcuts import render, redirect
# 导包
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
# 导入类视图
from django.views import View
import json
from django.core.serializers import serialize
from myapp.myser import UserSer
from rest_framework.response import Response
from rest_framework.views import APIView
# 导入加密库
import hashlib
# 导入图片库
# 绘画库
from PIL import ImageDraw
# 字体库
from PIL import ImageFont
# 图片库
from PIL import Image
# 随机库
import random
# 文件流
import io

import requests
import jwt_test

# 导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

# 导入原生sql模块
from django.db import connection

import jwt

# 导入redis数据库
import redis

# 导入时间模块
import time

# 导入公共目录变量
from mydjango.settings import BASE_DIR

# 导包
from django.db.models import Q, F

# 导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid

from .models import *

import redis


# 定义ip地址和端口
host = '127.0.0.1'
port = 6379

# 定义链接对象
r = redis.Redis(host=host,port=port)




from django.utils.deprecation import MiddlewareMixin

# 自定义中间件类
class MyMiddleWare(MiddlewareMixin):
    # 请求之前
    def process_request(self,request):
    #     uid = request.GET.get('uid')
    #     clinet_jwt = request.GET.get('jwt',None)
    #
    #     decode_jwt = jwt.decode(clinet_jwt, '123', algorithms=['HS256'])
    #     if decode_jwt['uid'] != str(uid):
    #
    #         return HttpResponse('你没有带上令牌')
        pass

    # 模板渲染之前
    def process_view(self,request,view_func,view_args,view_kwargs):
        pass
    # 请求之后
    def process_response(self,request,response):
        return response



# 装饰器
def my_decorator(func):
    def wrapper(request,*args,**kwargs):
        # print('这个装饰器被调用了')
        # print('请求接口是%s' % request.path)
        #
        # # 判断jwt逻辑
        # uid = request.GET.get('uid')
        # clinet_jwt = request.GET.get('jwt','None')
        #
        # decode_jwt = jwt.decode(clinet_jwt,'123',algorithms=['HS256'])
        # if decode_jwt['uid'] != str(uid):
        #     return HttpResponse('你篡改了用户ID')
        return func(request,*args,**kwargs)
    return wrapper


# 类装饰器调用
from django.utils.decorators import method_decorator


#用户信息
class UserInfo(APIView):
    @method_decorator(my_decorator)
    def get(self,request):
        uid = request.GET.get('uid')
        
        #查询数据
        user = User.objects.get(id=int(uid))

        #序列化对象
        user_ser = UserSer(user)

        return Response(user_ser.data)



# 更新用户数据
class UpdateUser(APIView):
    def get(self,request):

        img = request.GET.get('img')
        uid = request.GET.get('uid')

        print(img)
        print(uid)

        # 查询数据
        user = User.objects.get(id=int(uid))
        user.img = img
        user.save()

        return Response({
            'code':200,
            'message':'更新成功'
        })






# 定义七牛云存储接口
from qiniu import Auth

class QiNiu(APIView):
    def get(self,request):

        # 定义密钥
        q = Auth('BNJACqPq8b6i9Ljsp5pSc2y8gPrlh1qtKfvaX9-i','4UmG7vDrwM9Hs5DZftTlGXySuFl27P6yhzSmtQXo')

#         指定上传空间
        token = q.upload_token('1906b')

        print(token)

        res = {}

        res['token'] = token

        return Response(res)








# 定义验证码类
class MyCode(View):

    # 定义随机颜色
    def get_random_color(self):
        R = random.randrange(255)
        G = random.randrange(255)
        B = random.randrange(255)
        return (R,G,B)
    # 获取验证码视图
    def get(self,request):
        # 画布
        img_size = (120,50)
        # 定义画布对象
        image = Image.new('RGB',img_size,'white')
        # 定义画布对象
        draw = ImageDraw.Draw(image,'RGB')
        # 定义随机字符串
        source = '0123456789abcdef'
        # 容器
        code_str = ''
        # 定义字体
        my_font = ImageFont.truetype(font="c:\\Windows\\Fonts\\Arial.ttf",size=15)
        for i in range(4):
            #获取随机颜色
            text_color = self.get_random_color()
            # 获取随机字符串长度下标
            tmp_num = random.randrange(len(source))
            # 获取字符串
            random_str = source[tmp_num]
            # 添加到容器中
            code_str += random_str
            # 将字符串添加到画布中去
            draw.text((10+30*i,20),random_str,text_color,font=my_font)

        # 建立缓存区
        buf = io.BytesIO()

        # 将验证码存储到redis中
        r.set('code',code_str)

        # 将验证码导入session
        request.session['code'] = code_str
        print(request.session['code'])



        # 保存图片
        image.save(buf,'png')
        return HttpResponse(buf.getvalue(),'image/png')






# md5加密方法
def make_password(mypass):
    # 生成md5对象
    md5 = hashlib.md5()
    # 定义加密对象
    sign_str = str(mypass)
    # 转码
    sign_utf8 = sign_str.encode(encoding='utf-8')
    # 加密
    md5.update(sign_utf8)
    # 生成密钥串
    md5_server = md5.hexdigest()

    return md5_server


# 注册模块
class Register(APIView):

    def get(self, request):
        # 接收参数
        username = request.GET.get('username', 'null')
        password = request.GET.get('password', 'null')
        code = request.GET.get('code','null')

        print(username)
        print(password)
        print(code)

        # 获取验证码
        redis_code = r.get('code')
        # 转码
        redis_code = redis_code.decode('utf-8')
        print(redis_code)

        # 判断验证码是否正确
        # if code != redis_code:
        #     res = {}
        #     res['code'] = 405
        #     res['message'] = '验证码错误'
        #     return Response(res)

        # 获取session验证码
        session_code = request.session.get('code')
        print('session: %s' % str(session_code))

        if code != redis_code:
            res = {}
            res['code'] = 400
            res['message'] = '验证码输入错误'
            return Response(res)


        # 排重
        user = User.objects.filter(username=username).first()

        if user:
            res = {}
            res['code'] = 405
            res['message'] = '该用户名已经存在'
            return Response(res)

        # 入库
        user = User(username=username, password=make_password(password))
        user.save()

        res = {}
        res['code'] = 200
        res['message'] = '注册成功'

        return Response(res)



# 新浪微博回调
def wb_back(request):

    # 获取code
    code = request.GET.get('code')
    # 定义微博认证地址
    access_token_url = "https://api.weibo.com/oauth2/access_token"
    # 参数
    res = requests.post(
        access_token_url,
        data={
            "client_id":"3249062725",
            "client_secret":"544244413e2dc845fddd5a9b5ecf8170",
            "grant_type": "authorization_code",
            "code":code,
            "redirect_uri":"http://127.0.0.1:8000/md_admin/weibo"
    })

    # 转换类型
    res = json.loads(res.text)


    # 转换新浪微博昵称
    result = requests.get('https://api.weibo.com/2/users/show.json',params={'access_token':res['access_token'],'uid':res['uid']})
    result = json.loads(result.text)
    print(result)


    # //判断该用户是否曾经登陆过
    user = User.objects.filter(username=str(result['name'])).first()

    sina_id = ''
    user_id = ''

    if user:
        sina_id = user.username
        user_id = user.id
    else:
        # 手动创建账号
        user = User(username=str(result['name']),password='')
        user.save()

        sina_id = result['name']

        # 查询一下刚刚入库的账号id
        user = User.objects.filter(username=str(result['name'])).first()
        user_id = user.id

    # return HttpResponse(result['name'])

    return redirect("http://localhost:8080?sina_id="+sina_id+"&uid="+str(user_id))




import base64
import hmac
from hashlib import sha256
import urllib
import time
from urllib import parse

# 钉钉第三方登录
def dingding_back(request):
    # 获取code
    code = request.GET.get("code")

    t = time.time()

    timestamp = str((int(round(t * 1000))))
    appSecret = 'rDsIHGCcvj8wgd12KCafOUEwA2Vm8Uh9uhnvhvohwxwfXxGkwd86DLpR3d7n0McG'

    # 构造签名
    signature = base64.b64encode(hmac.new(appSecret.encode('utf-8'),timestamp.encode('utf-8'),digestmod=sha256).digest())

    # 请求接口，换取钉钉用户名
    payload = {'tmp_auth_code':code}
    headers = {'Content-Type':'application/json'}

    res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(signature.decode("utf-8")) + "&timestamp=" + timestamp + "&accessKey=dingoas0flvw1koxnmk1fa",data=json.dumps(payload), headers=headers)

    res_dict = json.loads(res.text)
    print(res_dict)
    # return HttpResponse(res.text)
    ding_nick = res_dict['user_info']['nick']


    user = User.objects.filter(username=ding_nick).first()

    user_id = ''

    if user:
        ding_nick = user.username
        user_id = user.id

    else:
        # 手动创建账号
        user = User(username=str(ding_nick),password='')
        user.save()

        # 查询一下刚刚入库的新账号id
        user = User.objects.filter(username=str(ding_nick)).first()
        user_id = user.id

    return redirect("http://localhost:8080?ding_nick=" + str(ding_nick)+"&uid="+str(user_id))



# 登陆模块
class Login(APIView):

    def get(self, request):
        # 获取用户名和密码
        username = request.GET.get('username')
        password = request.GET.get('password')

        print(username, password)

        # 查询用户
        user = User.objects.filter(username=username, password=make_password(password)).first()

        if user:
            # 加入jwt令牌机制
            # 进行编码
            encode_jwt = jwt.encode({'uid': str(user.id)}, '123', algorithm='HS256')

            # 解码
            # 强转
            encode_str = str(encode_jwt, 'utf-8')


            return Response({
                'code': 200,
                'message': '登陆成功',
                'username':user.username,
                'uid':user.id,
                'jwt':encode_str

            })
        return Response({
            'code': 405,
            'message': '用户名或密码错误'
        })


# 定义上传视图类
class UploadFile(View):

    def post(self, request):
        # 接受参数
        img = request.FILES.get('file')

        # 建立文件流对象
        f = open(os.path.join(UPLOAD_ROOT, '', img.name), 'wb')

        # 写入服务器
        for chunk in img.chunks():
            f.write(chunk)
        f.close()

        # 设置图片开打路径
        imgpath = './static/upload/' + img.name

        # 打开图片
        im = Image.open(r'{imgpath}'.format(imgpath=imgpath))
        # 生成画笔对象
        draw = ImageDraw.Draw(im)

        # 字体
        font = ImageFont.truetype(font='C:\\Windows\\Fonts\\simkai.ttf', size=100)

        # 修改图片
        draw.text((0, 0), 'nihao', fill=(76, 234, 124, 180), font=font)

        # 查看图片
        # im.show()

        # 存储图片
        im.save(r'{imgpath}'.format(imgpath=imgpath))

        # 返回文件名
        return HttpResponse(json.dumps({'filename': img.name}, ensure_ascii=False), content_type='application/json')



# 修改
class UpdatePass(APIView):
    def get(self, request):
        # 获取用户信息
        uid = request.GET.get('uid')
        password = request.GET.get('password')

        # 查询用户是否存在
        user = User.objects.filter(id=uid).first()
        print('++++++++++++++++++++++++++++++++++',user)
        print(request.GET.get('uid'))
        print(request.GET.get('password'))

        if user:
            user.password = make_password(password)
            user.save()

            return Response({
                'code': 200,
                'data': '修改成功'
            })

        return Response({
            'code': 405,
            'data': '修改失败'
        })










